package com.dayu.finecomm.iot;

import io.netty.channel.ChannelInitializer;

import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.URI;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TimeZone;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.dayu.finecomm.aop.AopProxy;
import com.dayu.finecomm.aop.adapt.mongo.AopFields;
import com.dayu.finecomm.aop.adapt.mongo.AopMongoAdapt;
import com.dayu.finecomm.aop.adapt.mongo.AopQueryItem;
import com.dayu.finecomm.iot.params.IotAopParam;
import com.dayu.finecomm.iot.params.IotCmdParam;
import com.dayu.finecomm.iot.params.IotDeviceParam;
import com.dayu.finecomm.iot.params.IotLogParam;
import com.dayu.finecomm.iot.params.IotPlatParam;
import com.dayu.finecomm.iot.params.IotQueryDataParam;
import com.dayu.finecomm.iot.service.IotHistoryDataDamon;
import com.dayu.finecomm.iot.service.IotPlatDamon;
import com.dayu.finecomm.iot.service.IotPlatServer;
import com.dayu.finecomm.mongo.pojo.IotDevice;
import com.dayu.finecomm.mongo.pojo.IotPlat;
import com.dayu.finecomm.mongo.service.IotPlatService;

/**
 * IotConsole, 处理鉴权登录、订阅服务、以及IOT平台的操作
 * 
 * @author XuJialiang
 * @since 2017-09-04 10:22:12
 * @version V1.0.0
 */
@Component
public class IotConsole {
	static Logger LOGGER = LoggerFactory.getLogger(IotConsole.class);

	private static final int ERROR_400 = 300400;
	private static final int ERROR_500 = 300500;
	private static final int ERROR_502 = 300502;
	private static final int ERROR_503 = 300503;

	private static final String ERROR_400_DESC = "Wrong request params.";
	private static final String ERROR_500_DESC = "Internal Server Error.";
	private static final String ERROR_502_DESC = "Connect iot plat failed.";
	private static final String ERROR_503_DESC = "Query historical data busy.";

	// private static final String PATTERN = "https://(\\S+):(\\d+)";

	@Autowired
	private AopMongoAdapt mLogMongoDB;

	/**
	 * IotConsole单例模式，静态变量
	 */
	private volatile static IotConsole mSelf = null;

	/**
	 * 错误响应信息
	 */
	private Map<Integer, String> mErrorMap;

	/**
	 * HTTP Server 获取IOT平台推送过来的请求消息
	 */
	IotPlatServer mHttpService;

	/**
	 * HTTP Server 是否开启
	 */
	private volatile int mHttpServerStatus;

	/**
	 * NA订阅callback URI
	 */
	private String mSubscribeCallback;

	/**
	 * IOT Plat 数据库
	 */
	private IotPlatService mMongoDB;

	/**
	 * 定时刷新RefreshToken线程
	 */
	IotPlatDamon mRefreshDamon;

	/**
	 * 定时处理设备历史数据
	 */
	IotHistoryDataDamon mHistoryDataDamon;

	/**
	 * 获取IotConsole单例模式
	 * 
	 * @return IotConsole
	 */
	public static IotConsole getInstance() {
		if (null == mSelf) {
			synchronized (IotConsole.class) {
				if (null == mSelf) {
					mSelf = new IotConsole();
				}
			}
		}

		return mSelf;
	}

	public IotConsole() {
		LOGGER.info("IotConsole constructor");

		mSelf = this;
		mErrorMap = null;
		mHttpServerStatus = 0;
		mSubscribeCallback = null;
		mMongoDB = null;
	}

	public void init(IotPlatService iotPlatService, String callbackURI,
			boolean refresh) {
		LOGGER.info("init iot");
		mErrorMap = new HashMap<Integer, String>();
		mErrorMap.put(ERROR_400, ERROR_400_DESC);
		mErrorMap.put(ERROR_500, ERROR_500_DESC);
		mErrorMap.put(ERROR_502, ERROR_502_DESC);
		mErrorMap.put(ERROR_503, ERROR_503_DESC);

		mMongoDB = iotPlatService;
		mSubscribeCallback = callbackURI;

		if (true == refresh) {
			LOGGER.info("init IotPlatDamon");

			mRefreshDamon = new IotPlatDamon(iotPlatService);
		}
	}

	/**
	 * 开启HTTP Server
	 * 
	 * @param host
	 *            主机名
	 * @param port
	 *            端口
	 * @param channel
	 *            处理IOT消息ChannelInitializer
	 * @return
	 */
	public int startHttpService(String host, int port,
			ChannelInitializer<?> channel) {
		int result = -1;

		if (0 == mHttpServerStatus) {
			if (null == host || host.isEmpty()) {
				try {
					host = getIpAddress();
				} catch (SocketException e) {
					LOGGER.error("getIpAddress error:" + e);
				}
			}

			LOGGER.info("User ip " + host + ":" + port
					+ " to start http server");

			IotDriverAdapter adapter = new IotDriverAdapter(channel);
			mHttpService = new IotPlatServer(host, port, adapter);

			if (null != mHttpService) {
				try {
					mHttpService.bootstrap();
					mHttpServerStatus = 1;

					LOGGER.info("init IotHistoryDataDamon");
					mHistoryDataDamon = new IotHistoryDataDamon(mMongoDB, host,
							port);

					result = 0;
				} catch (InterruptedException e) {
					mHttpServerStatus = 0;
					LOGGER.error("Start iot http service error: " + e);
				}
			}
		}

		return result;
	}

	/**
	 * 查询日志
	 * 
	 * @param record
	 * @return
	 */
	public String handleIotQueryLog(IotLogParam record) {
		String json = null;

		if (null != record) {
			if (null == record.subscribe) {
				record.subscribe = new String("deviceDatasChanged");
			}

			try {
				if (null != mLogMongoDB) {
					JSONArray devidArray = null;
					if (null != record.devid) {
						devidArray = JSONArray.parseArray(record.devid);
					}

					if (null != devidArray && devidArray.size() > 0) {

						JSONObject jsonResult = new JSONObject();
						JSONObject jsonResponse = new JSONObject();
						jsonResult.put("Code", 0);
						jsonResult.put("Response", jsonResponse);
						jsonResult.put("Message", null);

						Long startTime = 0L;
						if (null != record.startTime
								&& !record.startTime.isEmpty()) {
							startTime = getLongTime(record.startTime);

							jsonResponse.put("startTime", record.startTime);
						}

						Long endTime = 0L;
						if (null != record.endTime && !record.endTime.isEmpty()) {
							endTime = getLongTime(record.endTime);

							jsonResponse.put("endTime", record.endTime);
						}

						if (record.consume > 0) {
							jsonResponse.put("consume", record.consume);
						}

						AopQueryItem query = new AopQueryItem();
						query.path = new String(
								"com.dayu.finecomm.iot.handle.IotPlatInboundHandler");
						query.name = new String("channelRead");
						query.startTime = startTime;
						query.endTime = endTime;
						query.consume = record.consume;

						List<AopFields> list = mLogMongoDB.querys(query);

						for (int i = 0; i < devidArray.size(); i++) {
							String devid = devidArray.getString(i);
							JSONArray datas = new JSONArray();

							jsonResponse.put(devid, datas);
						}

						if (list != null) {
							for (AopFields item : list) {

								String arg = item.getArgs();
								String[] args = arg.split("\\|");

								if (args.length == 3) {
									String jsonString = args[2];

									JSONObject jsonObj = JSONObject
											.parseObject(jsonString);

									if (jsonObj.containsKey("requestId")) {
										String requestId = jsonObj
												.getString("requestId");
										if (0 == requestId
												.compareTo("historyDeviceDatas")) {
											continue;
										}
									}

									if (0 == "deviceDatasChanged"
											.compareTo(record.subscribe)) {
										if (false == jsonObj
												.containsKey("notifyType")) {
											continue;
										}
									} else {
										if (jsonObj.containsKey("notifyType")) {
											continue;
										}
									}

									String devId = jsonObj
											.getString("deviceId");

									JSONArray datas = jsonResponse
											.getJSONArray(devId);
									datas.add(JSONObject
											.toJSONString(
													jsonObj,
													SerializerFeature.WriteMapNullValue));
								}
							}
						} else {
							LOGGER.info("query log empty in mongodb");
						}

						json = JSONObject.toJSONString(jsonResult,
								SerializerFeature.WriteMapNullValue);
					} else {
						json = getErrorHttpResponse(ERROR_400);
					}
				} else {
					LOGGER.error("query mongodb error!!!");

					json = getErrorHttpResponse(ERROR_500);
				}
			} catch (Exception e) {
				LOGGER.error("query log error: " + e);

				json = getErrorHttpResponse(ERROR_500);
			}
		}

		return json;
	}

	/**
	 * 查询AOP日志
	 * 
	 * @param record
	 * @return
	 */
	public String handleIotQueryAop(IotAopParam record) {
		String json = null;

		if (null != record) {

			try {
				if (null != mLogMongoDB) {
					boolean fieldLevel = false;
					boolean fieldName = false;
					boolean fieldPath = false;
					boolean fieldArgs = false;
					boolean fieldResult = false;
					boolean fieldReqTime = false;
					boolean fieldRspTime = false;
					boolean fieldConsume = false;

					JSONArray queryFields = null;
					if (null != record.queryFields
							&& !record.queryFields.isEmpty()) {
						queryFields = JSONArray.parseArray(record.queryFields);

						for (int i = 0; i < queryFields.size(); i++) {
							String field = queryFields.getString(i);

							if (0 == field.compareTo("level")) {
								fieldLevel = true;
							} else if (0 == field.compareTo("name")) {
								fieldName = true;
							} else if (0 == field.compareTo("path")) {
								fieldPath = true;
							} else if (0 == field.compareTo("args")) {
								fieldArgs = true;
							} else if (0 == field.compareTo("result")) {
								fieldResult = true;
							} else if (0 == field.compareTo("reqTime")) {
								fieldReqTime = true;
							} else if (0 == field.compareTo("rspTime")) {
								fieldRspTime = true;
							} else if (0 == field.compareTo("consume")) {
								fieldConsume = true;
							} else {
								// None
							}
						}
					} else {
						fieldLevel = true;
						fieldName = true;
						fieldPath = true;
						fieldArgs = true;
						fieldResult = true;
						fieldReqTime = true;
						fieldRspTime = true;
						fieldConsume = true;
					}

					AopQueryItem query = new AopQueryItem();

					query.level = record.level;
					query.path = record.path;
					query.name = record.name;
					if (null != record.startTime && !record.startTime.isEmpty()) {
						query.startTime = getLongTime(record.startTime);
					} else {
						query.startTime = 0L;
					}
					if (null != record.endTime && !record.endTime.isEmpty()) {
						query.endTime = getLongTime(record.endTime);
					} else {
						query.endTime = 0L;
					}
					query.consume = record.consume;

					List<AopFields> list = mLogMongoDB.querys(query);

					JSONObject jsonResult = new JSONObject();
					JSONObject jsonResponse = new JSONObject();
					JSONArray jsonArray = new JSONArray();
					jsonResponse.put("count", 0);
					jsonResponse.put("records", jsonArray);
					jsonResult.put("Code", 0);
					jsonResult.put("Response", jsonResponse);
					jsonResult.put("Message", null);

					if (list != null) {
						jsonResponse.put("count", list.size());

						for (AopFields item : list) {
							JSONObject jsonItem = new JSONObject();

							if (true == fieldLevel) {
								jsonItem.put("level", item.getLevel());
							}

							if (true == fieldName) {
								jsonItem.put("name", item.getName());
							}

							if (true == fieldPath) {
								jsonItem.put("path", item.getPath());
							}

							if (true == fieldArgs) {
								jsonItem.put("args", item.getArgs());
							}

							if (true == fieldResult) {
								jsonItem.put("result", item.getResult());
							}

							if (true == fieldReqTime) {
								jsonItem.put("reqTime", item.getReqTime());
							}

							if (true == fieldRspTime) {
								jsonItem.put("rspTime", item.getRspTime());
							}

							if (true == fieldConsume) {
								jsonItem.put("consume", item.getConsume());
							}

							jsonArray.add(jsonItem);
						}
					}

					json = JSONObject.toJSONString(jsonResult,
							SerializerFeature.WriteMapNullValue);
				} else {
					LOGGER.error("query mongodb error!!!");

					json = getErrorHttpResponse(ERROR_500);
				}
			} catch (Exception e) {
				LOGGER.error("query aop error: " + e);

				json = getErrorHttpResponse(ERROR_500);
			}
		}

		return json;
	}

	public String handleDeleteApp(IotPlatParam record) {
		String json = null;

		if (null != record) {
			try {
				if (null != mMongoDB) {
					mMongoDB.delete(record.appid);

					JSONObject jsonObj = new JSONObject();

					jsonObj.put("Code", 0);
					jsonObj.put("Response", null);
					jsonObj.put("Message", null);

					json = JSONObject.toJSONString(jsonObj,
							SerializerFeature.WriteMapNullValue);

					LOGGER.info("delete app (" + record.appid
							+ ") successfully");
				} else {
					LOGGER.error("mongoDB server is null");

					json = getErrorHttpResponse(ERROR_500);
				}
			} catch (Exception e) {
				LOGGER.error("query application error: " + e);

				json = getErrorHttpResponse(ERROR_500);
			}
		}

		return json;
	}

	/**
	 * 查询APP应用
	 * 
	 * @return
	 */
	public String handleQueryApp() {
		String json = null;

		try {
			if (null != mMongoDB) {
				JSONObject jsonObj = new JSONObject();
				JSONArray jsonArr = new JSONArray();

				jsonObj.put("Code", 0);
				jsonObj.put("Response", jsonArr);
				jsonObj.put("Message", null);

				List<IotPlat> iotplats = mMongoDB.queryAll();

				for (IotPlat iotplat : iotplats) {
					JSONObject item = new JSONObject();
					item.put("appid", iotplat.getAppId());
					item.put("secret", iotplat.getSecret());
					item.put("service", iotplat.getService());
					item.put("protocol", iotplat.getProtocol());
					item.put("subscommandRsp", iotplat.getSubscribeCmds());
					item.put("subsdeviceDatasChanged",
							iotplat.getSubscribeDatas());

					jsonArr.add(item);
				}

				json = JSONObject.toJSONString(jsonObj,
						SerializerFeature.WriteMapNullValue);

				LOGGER.info("query app (" + iotplats.size() + ") items");
			} else {
				LOGGER.error("mongoDB server is null");

				json = getErrorHttpResponse(ERROR_500);
			}
		} catch (Exception e) {
			LOGGER.error("query application error: " + e);

			json = getErrorHttpResponse(ERROR_500);
		}

		return json;
	}

	/**
	 * 鉴权登录
	 * 
	 * @param record
	 *            iotplat
	 * @return
	 */
	public String handleIotAuth(IotPlatParam record) {
		String json = null;

		if (null != record) {
			IotHttpClientUtil client = null;

			try {

				client = new IotHttpClientUtil();
				client = AopProxy.instance().createAopProxy(
						IotHttpClientUtil.class, client);

				URI uri = new URI(record.service + "/iocm/app/sec/v1.1.0/login");
				String msg = new String("appId=" + record.appid + "&secret="
						+ record.secret);

				JSONObject jsonObj = client.doPost(uri.toString(), msg,
						IotHttpClientUtil.Method.POST,
						"application/x-www-form-urlencoded");
				int code = jsonObj.getIntValue("code");
				if (200 == code) {
					if (null != mMongoDB) {
						JSONObject body = jsonObj.getJSONObject("body");
						int expiresIn = body.getIntValue("expiresIn");
						String accessToken = body.getString("accessToken");
						String refreshToken = body.getString("refreshToken");

						IotPlat iotplat = new IotPlat();
						iotplat.setAppId(record.appid);
						iotplat.setSecret(record.secret);
						iotplat.setService(record.service);
						iotplat.setExpiresIn(expiresIn);
						iotplat.setAccessToken(accessToken);
						iotplat.setRefreshToken(refreshToken);
						iotplat.setProtocol(record.protocol);
						iotplat.setRefreshTime(new Date().getTime());
						iotplat.setSubscribeCmds(0);
						iotplat.setSubscribeDatas(0);

						mMongoDB.delete(iotplat.getAppId());
						mMongoDB.insert(iotplat);

						LOGGER.info("insert (" + record.appid + ", "
								+ record.protocol + ") to mongoDB");
					} else {
						LOGGER.error("mongoDB server is null");
					}
				}

				json = getHttpResponse(jsonObj);

			} catch (Exception e) {
				LOGGER.error("auth (" + record.service + ") error: " + e);

				json = getErrorHttpResponse(ERROR_500);
			}
		} else {
			json = getErrorHttpResponse(ERROR_400);
		}

		return json;
	}

	/**
	 * Refresh Token
	 * 
	 * @param record
	 * @return
	 */
	public String handleIotRefreshToken(IotPlatParam record) {
		String json = null;

		if (null != record) {
			IotHttpClientUtil client = null;

			try {
				record = fillIotPlatParam(record);

				client = new IotHttpClientUtil();
				client = AopProxy.instance().createAopProxy(
						IotHttpClientUtil.class, client);

				URI uri = new URI(record.service
						+ "/iocm/app/sec/v1.1.0/refreshToken");
				JSONObject reqJson = new JSONObject();
				reqJson.put("appId", record.appid);
				reqJson.put("secret", record.secret);
				reqJson.put("refreshToken", record.refreshToken);

				JSONObject jsonObj = client.doPost(uri.toString(),
						reqJson.toString(), IotHttpClientUtil.Method.POST,
						"application/json");
				int code = jsonObj.getIntValue("code");
				if (200 == code) {
					if (null != mMongoDB) {
						JSONObject body = jsonObj.getJSONObject("body");
						int expiresIn = body.getIntValue("expiresIn");
						String accessToken = body.getString("accessToken");
						String refreshToken = body.getString("refreshToken");

						IotPlat iotplat = mMongoDB.query(record.appid);

						iotplat.setExpiresIn(expiresIn);
						iotplat.setAccessToken(accessToken);
						iotplat.setRefreshToken(refreshToken);
						iotplat.setRefreshTime(new Date().getTime());

						mMongoDB.update(record.appid, iotplat);

						LOGGER.info("update (" + record.appid + ") to mongoDB");
					} else {
						LOGGER.error("mongoDB server is null");
					}
				}

				json = getHttpResponse(jsonObj);

			} catch (Exception e) {
				LOGGER.error("Refresh Token (" + record.service + ") error: "
						+ e);

				json = getErrorHttpResponse(ERROR_500);
			}
		} else {
			json = getErrorHttpResponse(ERROR_400);
		}

		return json;
	}

	/**
	 * NA订阅设备变更通知，当设备发生变更时平台会推送给NA
	 * 
	 * @param record
	 * @return
	 */
	public String subscribe(IotQueryDataParam record) {
		String result = null;
		JSONArray jsonRsp = null;
		JSONObject json = null;

		if (null != record) {
			IotHttpClientUtil client = null;

			try {
				record = (IotQueryDataParam) fillIotPlatParam((IotPlatParam) record);

				client = new IotHttpClientUtil(record.appid, record.token);
				client = AopProxy.instance().createAopProxy(
						IotHttpClientUtil.class, client);

				jsonRsp = new JSONArray();

				if (null != record.subscribe) {
					IotPlat iotplat = null;

					if (null != mMongoDB) {
						iotplat = mMongoDB.query(record.appid);
					}

					if (record.subscribe.subsbindDevice == 1) {
						String callback = mSubscribeCallback + "/ycb/iot/"
								+ record.appid + "/bindDevice";
						json = subscribe(client, record, "bindDevice", callback);
						jsonRsp.add(json);
					}

					if (record.subscribe.subsdeviceDeleted == 1) {
						String callback = mSubscribeCallback + "/ycb/iot/"
								+ record.appid + "/deviceDeleted";
						json = subscribe(client, record, "deviceDeleted",
								callback);
						jsonRsp.add(json);
					}

					if (record.subscribe.subsdeviceDataChanged == 1) {
						String callback = mSubscribeCallback + "/ycb/iot/"
								+ record.appid + "/deviceDataChanged";
						json = subscribe(client, record, "deviceDataChanged",
								callback);
						jsonRsp.add(json);
					}

					if (record.subscribe.subsdeviceDatasChanged == 1) {
						String callback = mSubscribeCallback + "/ycb/iot/"
								+ record.appid + "/deviceDatasChanged";
						json = subscribe(client, record, "deviceDatasChanged",
								callback);
						jsonRsp.add(json);

						if (201 == json.getIntValue("code")) {
							iotplat.setSubscribeDatas(1);
						} else {
							iotplat.setSubscribeDatas(0);
						}
					}

					if (record.subscribe.subscommandRsp == 1) {
						String callback = mSubscribeCallback + "/ycb/iot/"
								+ record.appid + "/commandRsp";
						json = subscribe(client, record, "commandRsp", callback);
						jsonRsp.add(json);

						if (201 == json.getIntValue("code")) {
							iotplat.setSubscribeCmds(1);
						} else {
							iotplat.setSubscribeCmds(0);
						}
					}

					if (null != mMongoDB && null != iotplat) {
						mMongoDB.update(record.appid, iotplat);
					}

					for (int i = 0; i < jsonRsp.size(); i++) {
						JSONObject obj = jsonRsp.getJSONObject(i);

						if (null != obj) {
							if (201 == obj.getIntValue("code")) {
								result = getHttpResponse(obj);
							} else {
								result = getHttpResponse(obj);
								break;
							}
						}
					}
				} else {
					result = getErrorHttpResponse(ERROR_400);
				}
			} catch (Exception e) {
				LOGGER.error("subscribe (" + record.service + ") error: " + e);

				result = getErrorHttpResponse(ERROR_500);
			}
		} else {
			result = getErrorHttpResponse(ERROR_400);
		}

		return result;
	}

	/**
	 * NA订阅设备变更通知，当设备发生变更时平台会推送给NA
	 * 
	 * @param client
	 *            HttpClient
	 * @param record
	 *            推送参数
	 * @param notifyType
	 *            推送类型
	 * @param callbackurl
	 *            回调地址(地址+端口)
	 * @return
	 */
	private JSONObject subscribe(IotHttpClientUtil client,
			IotQueryDataParam record, String notifyType, String callbackurl) {
		JSONObject json = null;

		if (null != client && false == notifyType.isEmpty()
				&& false == callbackurl.isEmpty()) {
			try {
				URI uri = new URI(record.service
						+ "/iocm/app/sub/v1.1.0/subscribe");

				JSONObject reqJson = new JSONObject();
				reqJson.put("notifyType", notifyType);
				reqJson.put("callbackurl", callbackurl);

				LOGGER.info("subscribe " + notifyType + ": " + callbackurl);

				json = client.doPost(uri.toString(), reqJson.toString(),
						IotHttpClientUtil.Method.POST, "application/json");
			} catch (Exception e) {
				LOGGER.error("subscribe (" + notifyType + ") error: " + e);

				JSONObject body = new JSONObject();
				body.put("error_code", String.valueOf(ERROR_500));
				body.put("error_desc", ERROR_500_DESC);

				json = new JSONObject();
				json.put("code", 500);
				json.put("body", body);
			}
		}

		return json;
	}

	/**
	 * NA向平台注册设备，设置设备的信息，待设备在南向完成安全接入IoT联接管理平台流程，设备将与app建立从属关系
	 * 
	 * @param param
	 *            注册设备参数
	 * @return
	 */
	public String handleRegDevice(IotDeviceParam record) {
		String json = null;

		if (null != record) {
			IotHttpClientUtil client = null;

			try {
				record = (IotDeviceParam) fillIotPlatParam((IotDeviceParam) record);

				client = new IotHttpClientUtil(record.appid, record.token);
				client = AopProxy.instance().createAopProxy(
						IotHttpClientUtil.class, client);

				URI uri = new URI(record.service
						+ "/iocm/app/reg/v1.1.0/devices");
				String strParam = "";
				if (null != record.appid && false == record.appid.isEmpty()) {
					strParam = "?appId=" + record.appid;
				}

				JSONObject reqJson = new JSONObject();
				reqJson.put("nodeId", record.device.nodeId);
				reqJson.put("verifyCode", record.device.verifyCode);
				reqJson.put("endUserId", record.device.endUserId);
				reqJson.put("timeout", 0);

				JSONObject jsonObj = client.doPost(uri.toString() + strParam,
						reqJson.toString(), IotHttpClientUtil.Method.POST,
						"application/json");

				int code = jsonObj.getIntValue("code");
				if (200 == code) {
					if (null != mMongoDB) {
						JSONObject body = jsonObj.getJSONObject("body");

						String devId = body.getString("deviceId");
						String verifyCode = body.getString("verifyCode");
						int timeout = body.getIntValue("timeout");
						String psk = body.getString("psk");

						IotDevice iotdevice = new IotDevice();

						iotdevice.setDeviceId(devId);
						iotdevice.setAppId(record.appid);
						iotdevice.setVerifyCode(verifyCode);
						iotdevice.setTimeout(timeout);
						iotdevice.setPsk(psk);
						iotdevice.setDeviceType("");
						iotdevice.setMfrsId("");
						iotdevice.setMfrsName("");
						iotdevice.setModel("");
						iotdevice.setProtocolType("");

						mMongoDB.deleteDev(iotdevice.getDeviceId());
						mMongoDB.insertDev(iotdevice);

						LOGGER.info("insertDev (" + devId + ") to mongoDB");
					}
				}

				json = getHttpResponse(jsonObj);

			} catch (Exception e) {
				LOGGER.error("regDevices (" + record.service + ") error: " + e);

				json = getErrorHttpResponse(ERROR_500);
			}
		} else {
			json = getErrorHttpResponse(ERROR_400);
		}

		return json;
	}

	/**
	 * NA设置或修改设备信息
	 * 
	 * @param record
	 * @return
	 */
	public String handleSetDevice(IotDeviceParam record) {
		String json = null;

		if (null != record) {
			IotHttpClientUtil client = null;

			try {
				record = (IotDeviceParam) fillIotPlatParam((IotDeviceParam) record);

				client = new IotHttpClientUtil(record.appid, record.token);
				client = AopProxy.instance().createAopProxy(
						IotHttpClientUtil.class, client);

				URI uri = new URI(record.service
						+ "/iocm/app/dm/v1.1.0/devices/"
						+ record.device.deviceId);
				String strParam = "";
				if (null != record.appid && false == record.appid.isEmpty()) {
					strParam = "?appId=" + record.appid;
				}

				JSONObject reqJson = new JSONObject();
				reqJson.put("deviceId", record.device.deviceId);
				reqJson.put("deviceType", record.device.deviceType);
				reqJson.put("manufacturerId", record.device.manufacturerId);
				reqJson.put("model", record.device.model);
				reqJson.put("protocolType", record.device.protocolType);
				reqJson.put("manufacturerName", record.device.manufacturerName);

				if (null != record.device.name
						&& false == record.device.name.isEmpty()) {
					reqJson.put("name", record.device.name);
				}

				if (null != record.device.endUser
						&& false == record.device.endUser.isEmpty()) {
					reqJson.put("endUser", record.device.endUser);
				}

				if (null != record.device.location
						&& false == record.device.location.isEmpty()) {
					reqJson.put("location", record.device.location);
				}

				JSONObject jsonObj = client.doPost(uri.toString() + strParam,
						reqJson.toString(), IotHttpClientUtil.Method.PUT,
						"application/json");

				int code = jsonObj.getIntValue("code");
				if (204 == code) {
					if (null != mMongoDB) {
						IotDevice iotdevice = mMongoDB
								.queryDev(record.device.deviceId);

						iotdevice.setDeviceType(record.device.deviceType);
						iotdevice.setMfrsId(record.device.manufacturerId);
						iotdevice.setMfrsName(record.device.manufacturerName);
						iotdevice.setModel(record.device.model);
						iotdevice.setProtocolType(record.device.protocolType);

						mMongoDB.updateDev(record.device.deviceId, iotdevice);

						LOGGER.info("updateDev (" + record.device.deviceId
								+ ") to mongoDB");
					}
				}

				json = getHttpResponse(jsonObj);

			} catch (Exception e) {
				LOGGER.error("Set device info (" + record.service + ") error: "
						+ e);

				json = getErrorHttpResponse(ERROR_500);
			}
		} else {
			json = getErrorHttpResponse(ERROR_400);
		}

		return json;
	}

	/**
	 * 给定设备的设备ID查询设备激活状态。当设备成功登录到平台后，平台设置设备状态为激活
	 * 
	 * @param record
	 * @return
	 */
	public String handleQueryDeviceState(IotDeviceParam record) {
		String json = null;

		if (null != record) {
			IotHttpClientUtil client = null;

			try {
				record = (IotDeviceParam) fillIotPlatParam((IotDeviceParam) record);

				client = new IotHttpClientUtil(record.appid, record.token);
				client = AopProxy.instance().createAopProxy(
						IotHttpClientUtil.class, client);

				URI uri = new URI(record.service
						+ "/iocm/app/reg/v1.1.0/devices/"
						+ record.device.deviceId);
				String strParam = "";
				if (null != record.appid && false == record.appid.isEmpty()) {
					strParam = "?appId=" + record.appid;
				}

				JSONObject jsonObj = client.doPost(uri.toString() + strParam,
						"", IotHttpClientUtil.Method.GET, "application/json");
				json = getHttpResponse(jsonObj);

			} catch (Exception e) {
				LOGGER.error("Query device active state (" + record.service
						+ ") error: " + e);

				json = getErrorHttpResponse(ERROR_500);
			}
		} else {
			json = getErrorHttpResponse(ERROR_400);
		}

		return json;
	}

	/**
	 * 删除设备
	 * 
	 * @param record
	 * @return
	 */
	public String handleDeleteDevice(IotDeviceParam record) {
		String json = null;

		if (null != record) {
			IotHttpClientUtil client = null;

			try {
				if (null == record.appid || record.appid.isEmpty()) {
					if (null != mMongoDB) {
						IotDevice iotdevice = mMongoDB
								.queryDev(record.device.deviceId);
						if (null != iotdevice) {
							record.appid = iotdevice.getAppId();
						}
					}
				}

				record = (IotDeviceParam) fillIotPlatParam((IotDeviceParam) record);

				client = new IotHttpClientUtil(record.appid, record.token);
				client = AopProxy.instance().createAopProxy(
						IotHttpClientUtil.class, client);

				URI uri = new URI(record.service
						+ "/iocm/app/dm/v1.1.0/devices/"
						+ record.device.deviceId);
				String strParam = "";
				if (null != record.appid && false == record.appid.isEmpty()) {
					strParam = "?appId=" + record.appid;
				}

				JSONObject jsonObj = client
						.doPost(uri.toString() + strParam, "",
								IotHttpClientUtil.Method.DELETE,
								"application/json");
				int code = jsonObj.getIntValue("code");
				if (204 == code) {
					if (null != mMongoDB) {
						mMongoDB.deleteDev(record.device.deviceId);
					}
				}

				json = getHttpResponse(jsonObj);

			} catch (Exception e) {
				LOGGER.error("Delete device (" + record.service + ") error: "
						+ e);

				json = getErrorHttpResponse(ERROR_500);
			}
		} else {
			json = getErrorHttpResponse(ERROR_400);
		}

		return json;
	}

	/**
	 * NA对单个应用下设备状态进行配置。 对周期性上报数据的设备,平台可以根据设备上报数据的时间来检测设备的状态，
	 * 如果设备在设定的周期内正常上报数据，则状态为online，否则状态为abnormal或offline。
	 * 
	 * @param record
	 * @return
	 */
	public String handleSetApplication(IotDeviceParam record) {
		String json = null;

		if (null != record) {
			IotHttpClientUtil client = null;

			try {
				record = (IotDeviceParam) fillIotPlatParam((IotDeviceParam) record);

				client = new IotHttpClientUtil(record.appid, record.token);
				client = AopProxy.instance().createAopProxy(
						IotHttpClientUtil.class, client);

				URI uri = new URI(record.service
						+ "/iocm/app/am/v1.1.0 /applications/" + record.appid);

				JSONObject reqJson = new JSONObject();
				JSONObject config = new JSONObject();
				config.put("abnormalTime", record.app.abnormalTime);
				config.put("offlineTime", record.app.offlineTime);
				reqJson.put("deviceStatusTimeConfig", config);

				JSONObject jsonObj = client.doPost(uri.toString(),
						reqJson.toString(), IotHttpClientUtil.Method.PUT,
						"application/json");
				json = getHttpResponse(jsonObj);

			} catch (Exception e) {
				LOGGER.error("Set Application (" + record.service + ") error: "
						+ e);

				json = getErrorHttpResponse(ERROR_500);
			}
		} else {
			json = getErrorHttpResponse(ERROR_400);
		}

		return json;
	}

	/**
	 * 更新单个设备地理位置信息，此信息用于在地图上显示设备
	 * 
	 * @param record
	 * @return
	 */
	public String handleUpdateLocation(IotDeviceParam record) {
		String json = null;

		if (null != record) {
			IotHttpClientUtil client = null;

			try {
				record = (IotDeviceParam) fillIotPlatParam((IotDeviceParam) record);

				client = new IotHttpClientUtil(record.appid, record.token);
				client = AopProxy.instance().createAopProxy(
						IotHttpClientUtil.class, client);

				URI uri = new URI(record.service
						+ "/iocm/app/location/v1.1.0/devices/"
						+ record.device.deviceId);
				String strParam = "";
				if (null != record.appid && false == record.appid.isEmpty()) {
					strParam = "?appId=" + record.appid;
				}

				JSONObject reqJson = new JSONObject();
				reqJson.put("latitude", record.location.latitude);
				reqJson.put("longitude", record.location.longitude);
				reqJson.put("accuracy", record.location.accuracy);

				if (null != record.location.description
						&& false == record.location.description.isEmpty()) {
					reqJson.put("description", record.location.description);
				}

				if (null != record.location.region
						&& false == record.location.region.isEmpty()) {
					reqJson.put("region", record.location.region);
				}

				JSONObject jsonObj = client.doPost(uri.toString() + strParam,
						reqJson.toString(), IotHttpClientUtil.Method.PUT,
						"application/json");
				json = getHttpResponse(jsonObj);

			} catch (Exception e) {
				LOGGER.error("Query device active state (" + record.service
						+ ") error: " + e);

				json = getErrorHttpResponse(ERROR_500);
			}
		} else {
			json = getErrorHttpResponse(ERROR_400);
		}

		return json;
	}

	/**
	 * 按条件批量查询设备信息列表
	 * 
	 * @param record
	 * @return
	 */
	public String handleQueryAllDevices(IotQueryDataParam record) {
		String json = null;

		if (null != record) {
			IotHttpClientUtil client = null;

			try {
				record = (IotQueryDataParam) fillIotPlatParam((IotQueryDataParam) record);

				client = new IotHttpClientUtil(record.appid, record.token);
				client = AopProxy.instance().createAopProxy(
						IotHttpClientUtil.class, client);

				String strURI = record.service + "/iocm/app/dm/v1.1.0/devices";
				String strParam = "?";

				if (null != record.devsCond) {
					if (null != record.appid && false == record.appid.isEmpty()) {
						strParam += "appId=" + record.appid + "&";
					}

					if (null != record.devsCond.gatewayId
							&& false == record.devsCond.gatewayId.isEmpty()) {
						strParam += "gatewayId=" + record.devsCond.gatewayId
								+ "&";
					}

					if (-1 != record.devsCond.pageNo) {
						strParam += "pageNo=" + record.devsCond.pageNo + "&";
					}

					if (null != record.devsCond.nodeType
							&& false == record.devsCond.nodeType.isEmpty()) {
						strParam += "nodeType=" + record.devsCond.nodeType
								+ "&";
					}

					if (null != record.devsCond.deviceType
							&& false == record.devsCond.deviceType.isEmpty()) {
						strParam += "deviceType=" + record.devsCond.deviceType
								+ "&";
					}

					if (-1 != record.devsCond.pageSize) {
						strParam += "pageSize=" + record.devsCond.pageSize
								+ "&";
					}

					if (null != record.devsCond.status
							&& false == record.devsCond.status.isEmpty()) {
						strParam += "status=" + record.devsCond.status + "&";
					}

					if (null != record.devsCond.startTime
							&& false == record.devsCond.startTime.isEmpty()) {
						strParam += "startTime=" + record.devsCond.startTime
								+ "&";
					}

					if (null != record.devsCond.endTime
							&& false == record.devsCond.endTime.isEmpty()) {
						strParam += "endTime=" + record.devsCond.endTime + "&";
					}

					if (null != record.devsCond.sort
							&& false == record.devsCond.sort.isEmpty()) {
						strParam += "sort=" + record.devsCond.sort + "&";
					}
				}

				strParam = strParam.substring(0, strParam.length() - 1);

				URI uri = new URI(strURI);

				JSONObject jsonObj = client.doPost(uri.toString() + strParam,
						"", IotHttpClientUtil.Method.GET, "application/json");
				json = getHttpResponse(jsonObj);

			} catch (Exception e) {
				LOGGER.error("Query all devices (" + record.service
						+ ") error: " + e);

				json = getErrorHttpResponse(ERROR_500);
			}
		} else {
			json = getErrorHttpResponse(ERROR_400);
		}

		return json;
	}

	/**
	 * 查询指定条件的设备信息
	 * 
	 * @param record
	 * @return
	 */
	public String handleQueryDevice(IotQueryDataParam record) {
		String json = null;

		if (null != record) {
			IotHttpClientUtil client = null;

			try {
				record = (IotQueryDataParam) fillIotPlatParam((IotQueryDataParam) record);

				client = new IotHttpClientUtil(record.appid, record.token);
				client = AopProxy.instance().createAopProxy(
						IotHttpClientUtil.class, client);

				String strURI = record.service + "/iocm/app/dm/v1.1.0/devices/";
				strURI += record.devCond.deviceId;

				String strParam = "";
				if (null != record.appid && false == record.appid.isEmpty()) {
					strParam += "?appId=" + record.appid;
				}

				URI uri = new URI(strURI);

				JSONObject jsonObj = client.doPost(uri.toString() + strParam,
						"", IotHttpClientUtil.Method.GET, "application/json");

				JSONObject body = jsonObj.getJSONObject("body");

				if (null != body && false == body.containsKey("error_code")) {
					IotDevice iotdevice = null;
					if (null != mMongoDB) {
						iotdevice = mMongoDB.queryDev(record.devCond.deviceId);
					}

					JSONObject jsonDevInfo = body.getJSONObject("deviceInfo");

					JSONObject jsonDev = new JSONObject();
					jsonDev.put("deviceId", body.get("deviceId"));
					// jsonDev.put("imei", jsonDevInfo.get("nodeId"));
					jsonDev.put("imei", "");
					if (null != iotdevice) {
						jsonDev.put("imei", iotdevice.getVerifyCode());
					}

					jsonDev.put("manufacturerId",
							jsonDevInfo.get("manufacturerId"));

					if (null != jsonDevInfo.get("manufacturerName")) {
						jsonDev.put("manufacturerName",
								jsonDevInfo.get("manufacturerName"));
					} else {
						jsonDev.put("manufacturerName", "");
					}

					jsonDev.put("deviceType", jsonDevInfo.get("deviceType"));

					if (jsonDevInfo.containsKey("model")) {
						jsonDev.put("model", jsonDevInfo.get("model"));
					} else {
						jsonDev.put("model", "");
						if (null != iotdevice) {
							jsonDev.put("model", iotdevice.getModel());
						}
					}

					jsonDev.put("protocolType", jsonDevInfo.get("protocolType"));

					if (null != jsonDevInfo.get("status")) {
						jsonDev.put("status", jsonDevInfo.get("status"));
					} else {
						jsonDev.put("status", "UNKNOWN");
					}

					jsonObj.put("body", jsonDev);
				}

				json = getHttpResponse(jsonObj);

			} catch (Exception e) {
				LOGGER.error("Query single device (" + record.service
						+ ") error: " + e);

				json = getErrorHttpResponse(ERROR_500);
			}
		} else {
			json = getErrorHttpResponse(ERROR_400);
		}

		return json;
	}

	/**
	 * NA查询设备历史数据
	 * 
	 * @param record
	 * @return
	 */
	public String handleQueryHistoryDevice(IotQueryDataParam record) {
		String json = null;

		if (null != record) {
			IotHttpClientUtil client = null;

			try {
				record = (IotQueryDataParam) fillIotPlatParam((IotQueryDataParam) record);

				client = new IotHttpClientUtil(record.appid, record.token);
				client = AopProxy.instance().createAopProxy(
						IotHttpClientUtil.class, client);

				String strURI = record.service
						+ "/iocm/app/data/v1.1.0/deviceDataHistory";
				String strParam = "?";

				if (null != record.historyCond) {
					if (null != record.historyCond.deviceId
							&& false == record.historyCond.deviceId.isEmpty()) {
						strParam += "deviceId=" + record.historyCond.deviceId
								+ "&";
					}

					if (null != record.appid && false == record.appid.isEmpty()) {
						strParam += "appId=" + record.appid + "&";
					}

					if (null != record.historyCond.gatewayId
							&& false == record.historyCond.gatewayId.isEmpty()) {
						strParam += "gatewayId=" + record.historyCond.gatewayId
								+ "&";
					}

					if (null != record.historyCond.serviceId
							&& false == record.historyCond.serviceId.isEmpty()) {
						strParam += "serviceId=" + record.historyCond.serviceId
								+ "&";
					}

					if (-1 != record.historyCond.pageNo) {
						strParam += "pageNo=" + record.historyCond.pageNo + "&";
					}

					if (-1 != record.historyCond.pageSize) {
						strParam += "pageSize=" + record.historyCond.pageSize
								+ "&";
					}

					if (null != record.historyCond.startTime
							&& false == record.historyCond.startTime.isEmpty()) {
						strParam += "startTime=" + record.historyCond.startTime
								+ "&";
					}

					if (null != record.historyCond.endTime
							&& false == record.historyCond.endTime.isEmpty()) {
						strParam += "endTime=" + record.historyCond.endTime
								+ "&";
					}
				}

				strParam = strParam.substring(0, strParam.length() - 1);

				URI uri = new URI(strURI);

				JSONObject jsonObj = client.doPost(uri.toString() + strParam,
						"", IotHttpClientUtil.Method.GET, "application/json");

				if (200 == jsonObj.getIntValue("code")) {
					JSONObject jsonBody = new JSONObject();

					jsonObj.getJSONObject("body").put("appId", record.appid);

					// 将历史数据交由后台处理
					if (0 == mHistoryDataDamon.putHistoryData(jsonObj)) {
						jsonBody.put("Code", 0);

						JSONObject jsonRsp = new JSONObject();
						jsonRsp.put("totalCount", jsonObj.getJSONObject("body")
								.getIntValue("totalCount"));
						jsonBody.put("Response", jsonRsp);
						jsonBody.put("Message", null);
					} else {
						jsonBody.put("Code", ERROR_503);
						jsonBody.put("Response", null);
						jsonBody.put("Message", mErrorMap.get(ERROR_503));
					}

					json = jsonBody.toString();
				} else {
					json = getHttpResponse(jsonObj);
				}

			} catch (Exception e) {
				LOGGER.error("Query history device (" + record.service
						+ ") error: " + e);

				json = getErrorHttpResponse(ERROR_500);
			}
		} else {
			json = getErrorHttpResponse(ERROR_400);
		}

		return json;
	}

	/**
	 * 查询设备的服务能力
	 * 
	 * @param record
	 * @return
	 */
	public String handleQueryDeviceCapability(IotQueryDataParam record) {
		String json = null;

		if (null != record) {
			IotHttpClientUtil client = null;

			try {
				record = (IotQueryDataParam) fillIotPlatParam((IotQueryDataParam) record);

				client = new IotHttpClientUtil(record.appid, record.token);
				client = AopProxy.instance().createAopProxy(
						IotHttpClientUtil.class, client);

				String strURI = record.service
						+ "/iocm/app/data/v1.1.0/deviceCapabilities";
				String strParam = "?deviceId=" + record.capabilityCond.deviceId;

				if (null != record.appid && false == record.appid.isEmpty()) {
					strParam += "&appId=" + record.appid;
				}

				URI uri = new URI(strURI);

				JSONObject jsonObj = client.doPost(uri.toString() + strParam,
						"", IotHttpClientUtil.Method.GET, "application/json");
				json = getHttpResponse(jsonObj);

			} catch (Exception e) {
				LOGGER.error("Query device capability (" + record.service
						+ ") error: " + e);

				json = getErrorHttpResponse(ERROR_500);
			}
		} else {
			json = getErrorHttpResponse(ERROR_400);
		}

		return json;
	}

	/**
	 * NA发送命令给设备
	 * 
	 * @param record
	 * @return
	 */
	public String handlePostCmdToDevice(IotCmdParam record) {
		String json = null;

		if (null != record) {
			IotHttpClientUtil client = null;

			try {
				record = (IotCmdParam) fillIotPlatParam((IotCmdParam) record);

				client = new IotHttpClientUtil(record.appid, record.token);
				client = AopProxy.instance().createAopProxy(
						IotHttpClientUtil.class, client);

				String strURI = record.service
						+ "/iocm/app/cmd/v1.3.0/devices/";
				strURI += record.postCmd.deviceId + "/commands";

				URI uri = new URI(strURI);

				JSONObject body = new JSONObject();
				if (null != record.postCmd.requestId
						&& false == record.postCmd.requestId.isEmpty()) {
					body.put("requestId", record.postCmd.requestId);
				}

				JSONObject cmd = new JSONObject();
				cmd.put("serviceId", record.postCmd.command.serviceId);
				cmd.put("method", record.postCmd.command.method);

				JSONObject paras = JSON
						.parseObject(record.postCmd.command.paras);
				cmd.put("paras", paras);
				body.put("command", cmd);

				if (null != record.postCmd.callbackUrl
						&& false == record.postCmd.callbackUrl.isEmpty()) {
					body.put("callbackUrl", record.postCmd.callbackUrl);
				}

				if (-1 != record.postCmd.expireTime) {
					body.put("expireTime", record.postCmd.expireTime);
				}

				JSONObject jsonObj = client.doPost(uri.toString(),
						body.toString(), IotHttpClientUtil.Method.POST,
						"application/json");
				json = getHttpResponse(jsonObj);

			} catch (Exception e) {
				LOGGER.error("Post cmd to device (" + record.service
						+ ") error: " + e);

				json = getErrorHttpResponse(ERROR_500);
			}
		} else {
			json = getErrorHttpResponse(ERROR_400);
		}

		return json;
	}

	/**
	 * NA按条件批量查询下发的命令
	 * 
	 * @param record
	 * @return
	 */
	public String handleQueryDeviceCmds(IotCmdParam record) {
		String json = null;

		if (null != record) {
			IotHttpClientUtil client = null;

			try {
				record = (IotCmdParam) fillIotPlatParam((IotCmdParam) record);

				client = new IotHttpClientUtil(record.appid, record.token);
				client = AopProxy.instance().createAopProxy(
						IotHttpClientUtil.class, client);

				String strURI = record.service
						+ "/iocm/app/cmd/v1.2.0/queryCmd";
				String strParam = "?";

				if (null != record.queryCmds) {
					if (null != record.queryCmds.deviceId
							&& false == record.queryCmds.deviceId.isEmpty()) {
						strParam += "deviceId=" + record.queryCmds.deviceId
								+ "&";
					}

					if (null != record.appid && false == record.appid.isEmpty()) {
						strParam += "appId=" + record.appid + "&";
					}

					if (-1 != record.queryCmds.pageNo) {
						strParam += "pageNo=" + record.queryCmds.pageNo + "&";
					}

					if (-1 != record.queryCmds.pageSize) {
						strParam += "pageSize=" + record.queryCmds.pageSize
								+ "&";
					}

					if (null != record.queryCmds.startTime
							&& false == record.queryCmds.startTime.isEmpty()) {
						strParam += "startTime=" + record.queryCmds.startTime
								+ "&";
					}

					if (null != record.queryCmds.endTime
							&& false == record.queryCmds.endTime.isEmpty()) {
						strParam += "endTime=" + record.queryCmds.endTime + "&";
					}
				}

				strParam = strParam.substring(0, strParam.length() - 1);

				URI uri = new URI(strURI);

				JSONObject jsonObj = client.doPost(uri.toString() + strParam,
						"", IotHttpClientUtil.Method.GET, "application/json");
				json = getHttpResponse(jsonObj);

			} catch (Exception e) {
				LOGGER.error("Query device cmds (" + record.service
						+ ") error: " + e);

				json = getErrorHttpResponse(ERROR_500);
			}
		} else {
			json = getErrorHttpResponse(ERROR_400);
		}

		return json;
	}

	/**
	 * NA修改命令信息
	 * 
	 * @param record
	 * @return
	 */
	public String handleModifyCmds(IotCmdParam record) {
		String json = null;

		if (null != record) {
			IotHttpClientUtil client = null;

			try {
				record = (IotCmdParam) fillIotPlatParam((IotCmdParam) record);

				client = new IotHttpClientUtil(record.appid, record.token);
				client = AopProxy.instance().createAopProxy(
						IotHttpClientUtil.class, client);

				String strURI = record.service
						+ "/iocm/app/cmd/v1.2.0/devices/";
				strURI += record.modifyCmd.deviceId + "/commands/"
						+ record.modifyCmd.commandId;

				String strParam = "";
				if (null != record.appid && false == record.appid.isEmpty()) {
					strParam += "?appId=" + record.appid;
				}

				URI uri = new URI(strURI);

				JSONObject body = new JSONObject();
				JSONObject result = new JSONObject();
				result.put("resultCode", record.modifyCmd.result.resultCode);

				JSONObject detail = JSON
						.parseObject(record.modifyCmd.result.resultDetail);
				result.put("resultDetail", detail);
				body.put("result", result);

				JSONObject jsonObj = client.doPost(uri.toString() + strParam,
						body.toString(), IotHttpClientUtil.Method.PUT,
						"application/json");
				json = getHttpResponse(jsonObj);

			} catch (Exception e) {
				LOGGER.error("Modify cmd (" + record.service + ") error: " + e);

				json = getErrorHttpResponse(ERROR_500);
			}
		} else {
			json = getErrorHttpResponse(ERROR_400);
		}

		return json;
	}

	/**
	 * NA查询下发的单个命令
	 * 
	 * @param record
	 * @return
	 */
	public String handleQueryDeviceCmd(IotCmdParam record) {
		String json = null;

		if (null != record) {
			IotHttpClientUtil client = null;

			try {
				record = (IotCmdParam) fillIotPlatParam((IotCmdParam) record);

				client = new IotHttpClientUtil(record.appid, record.token);
				client = AopProxy.instance().createAopProxy(
						IotHttpClientUtil.class, client);

				String strURI = record.service
						+ "/iocm/app/cmd/v1.3.0/devices/";
				strURI += record.queryCmd.deviceId + "/commands/"
						+ record.queryCmd.commandId;

				URI uri = new URI(strURI);

				JSONObject jsonObj = client.doPost(uri.toString(), "",
						IotHttpClientUtil.Method.GET, "application/json");
				json = getHttpResponse(jsonObj);

			} catch (Exception e) {
				LOGGER.error("Query device cmd (" + record.service
						+ ") error: " + e);

				json = getErrorHttpResponse(ERROR_500);
			}
		} else {
			json = getErrorHttpResponse(ERROR_400);
		}

		return json;
	}

	/**
	 * 获取本地上线的IP地址，不包括Loop Back和虚拟地址
	 * 
	 * @return
	 * @throws SocketException
	 */
	public static String getIpAddress() throws SocketException {
		String ip = null;

		Enumeration<NetworkInterface> interfaces = NetworkInterface
				.getNetworkInterfaces();

		while (interfaces.hasMoreElements()) {
			NetworkInterface current = interfaces.nextElement();

			if (!current.isUp() || current.isLoopback() || current.isVirtual()) {
				continue;
			}

			Enumeration<InetAddress> addresses = current.getInetAddresses();
			while (addresses.hasMoreElements()) {
				InetAddress addr = addresses.nextElement();

				if (addr.isLoopbackAddress()) {
					continue;
				}

				ip = addr.getHostAddress();

				LOGGER.info("getIpAddress " + ip + " for http server");

				return ip;
			}
		}

		throw new SocketException("Can't get our ip address, interfaces are: "
				+ interfaces);
	}

	/**
	 * 补充iotplat 参数
	 * 
	 * @param record
	 * @return
	 */
	private IotPlatParam fillIotPlatParam(IotPlatParam record) {
		try {
			IotPlat iotplat = mMongoDB.query(record.appid);

			if (null == record.secret || true == record.secret.isEmpty()) {
				record.secret = iotplat.getSecret();
			}

			if (null == record.service || true == record.service.isEmpty()) {
				record.service = iotplat.getService();
			}

			if (null == record.token || true == record.token.isEmpty()) {
				record.token = iotplat.getAccessToken();
			}

			if (null == record.refreshToken
					|| true == record.refreshToken.isEmpty()) {
				record.refreshToken = iotplat.getRefreshToken();
			}

			return record;
		} catch (Exception e) {
			LOGGER.error("Fill IotPlatParam error, appid=" + record.appid);

			throw e;
		}
	}

	/**
	 * 返回错误Http响应信息
	 * 
	 * @param error
	 * @return
	 */
	private String getErrorHttpResponse(int error) {
		String response = "";
		JSONObject json = null;

		if (mErrorMap.containsKey(error)) {
			json = new JSONObject();
			json.put("Code", error);
			json.put("Response", null);
			json.put("Message", mErrorMap.get(error));

			response = JSONObject.toJSONString(json,
					SerializerFeature.WriteMapNullValue);
		}

		return response;
	}

	/**
	 * 返回Http响应信息
	 * 
	 * @param json
	 * @return
	 */
	private String getHttpResponse(JSONObject json) {
		String response = "";

		if (null != json) {
			JSONObject result = new JSONObject();

			JSONObject body = json.getJSONObject("body");

			if (null != body) {
				if (body.containsKey("error_code")) {
					result.put("Code", body.getInteger("error_code"));
					result.put("Response", null);
					result.put("Message", body.getString("error_desc"));
				} else if (body.containsKey("deviceCapabilities")) {
					result.put("Code", 0);
					result.put("Response",
							body.getJSONArray("deviceCapabilities"));
					result.put("Message", null);
				} else {
					result.put("Code", 0);
					result.put("Response", body);
					result.put("Message", null);
				}
			} else {
				result.put("Code", 0);
				result.put("Response", null);
				result.put("Message", null);
			}

			response = JSONObject.toJSONString(result,
					SerializerFeature.WriteMapNullValue);
		}

		return response;
	}

	/**
	 * 获取时间戳
	 * 
	 * @param time
	 * @return
	 * @throws Exception
	 */
	private long getLongTime(String time) throws Exception {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		sdf.setTimeZone(TimeZone.getTimeZone("GMT+8"));
		Date sTime = sdf.parse(time);

		return sTime.getTime();
	}
}
